/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.TX;

import Helper.TTAHelper.Helper_Cluster;
import entity.Country;
import entity.Users;
import entity.tta.OutletDataModel;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author Lu Xiaodi
 */
@Stateless
public class ItineraryPlannerSB implements ItineraryPlannerSBRemote {

    @PersistenceContext
    EntityManager em;

    public List<Helper_Cluster> recommendOutletId(Long userId) {
        // get ageGroupsIdx and countriesIdx
        Users user = em.find(Users.class, userId);
        if (user == null) {
            // throw usernotfound exception
            return null;
        }
//        int ageGroupsIdx = this.computeAgeGroupsIdx(user);
        int ageGroupsIdx = 0;
//        int countriesIdx = this.computeCountriesIdx(user);
        int countriesIdx = 0;

        // get helper_cluster for all outlet data models (stored in List clusters)
        Query query = em.createQuery("SELECT o FROM OutletDataModel o");
        List<OutletDataModel> allOutletDataModels = query.getResultList();
        List<Helper_Cluster> allClusters = new ArrayList<Helper_Cluster>();
        for (OutletDataModel o : allOutletDataModels) {
            allClusters.add(new Helper_Cluster(o.getOutletId(), o.getCluster()[countriesIdx][ageGroupsIdx]));
        }
        allOutletDataModels = null;

        List<Helper_Cluster> top10Cluster = this.getTop10(allClusters);

        return top10Cluster;
    }

    private int computeAge(Users user) {
        Calendar birthdate = Calendar.getInstance();
        birthdate.setTime(user.getBirthDate());
        Calendar systemTime = Calendar.getInstance();
        systemTime.setTime(new Date());
        int age = systemTime.get(Calendar.YEAR) - birthdate.get(Calendar.YEAR);
        return age;
    }

    /**
     * List of countries:
     * 1. Southeast Asia: Thailand, Vietnam, Other Countries in Southeast Asia
     * 2. North Asia: P R China, Taiwan, Hong Kong SAR, Japan, South Koria, Other Countries in North Asia
     * 3. South Asia: Bangladesh, India, Nepal, Pakistan, Sri Lanka, Other Countries in South Asia
     * 4. West Asia: Iran, Israel, Kuwait, Saudi Arabia, United Arab Emirates, Other Countries in West Asia
     * 5. Europe: Austria, Belgium & Luxembourg, Denmark, Finland, France, Germany, Greece, Italy, Netherlands,
    Norway, Porland, Rep of Ireland, Russian Federation, Spain, Sweden, Switzerland, Turkey, UK, 
    Other Countries in Eastern Europe, Other Countries in Western Europe
     * 6. Occeania: Australia, New Zealand, Other Countries in Oceania
     * 7. Africa: Egypt, Mauritius, South Africa (Rep of), Other Countries in Africa
     * 8. Americas: Canada, USA, other countries in Americas
     */
    private int computeCountriesIdx(Users user) {
        String country = user.getCountry().getCountry();
        OutletDataModel model = new OutletDataModel();
        String[] countries = model.getCountriesArray();
        for (int i = 0; i < countries.length; i++) {
            if (countries[i].trim().equalsIgnoreCase(country)) {
                return i;
            }
        }
        return -1;
    }

    private int computeAgeGroupsIdx(Users user) {
        int age = this.computeAge(user);
        OutletDataModel model = new OutletDataModel();
        String[] ageGroups = model.getAgeGroupsArray();

        for (int i = 0; i < ageGroups.length; i++) {
            String[] ageBoundaries = ageGroups[i].split("-");
            Integer minAge = new Integer(ageBoundaries[0]);
            Integer maxAge = new Integer(ageBoundaries[1]);
            if (minAge <= age && age <= maxAge) {
                return i;
            }
        }
        return -1;
    }

    private List<Helper_Cluster> getTop10(List<Helper_Cluster> inputCluster) {
        List<Helper_Cluster> returnList = new ArrayList<Helper_Cluster>();
        for (int i = 0; i < inputCluster.size(); i++) {
            Helper_Cluster aCluster = inputCluster.get(i);
            // for the first 10 clusters, just add
            if (i < 10) {
                returnList.add(aCluster);
            } // for 10+ cluster, see if it is within top 20. if so, add it into proper position of returnLsist,
            // and delete the last element from returnList.
            else {
                for (int j = 0; j < returnList.size(); j++) {
                    if (returnList.get(j).getPopularity() <= aCluster.getPopularity()) {
                        returnList.add(j, aCluster);
                        returnList.remove(returnList.size() - 1);
                    }
                }
            }
        }
        return returnList;
    }

    public void createUser_Test(String email, String country, int birthYear) {
        Users user = new Users();
        user.setEmail(email);
        
        // Find the Country
        Query q1 = em.createQuery("SELECT c FROM Country C WHERE c.country = :paramcountry");
        q1.setParameter("paramcountry", country);
        
        for(Object o : q1.getResultList()){
            Country c = (Country)o;
            if(c.getCountry().equalsIgnoreCase(country)){
                user.setCountry(c);
                break;
            }
        }
        
        
        Calendar c = Calendar.getInstance();
        c.set(birthYear, 1, 1);
        user.setBirthDate(c.getTime());
        em.persist(user);
    }

    public List<String> printUser_Test() {
        Query query = em.createQuery("SELECT u FROM Users u");
        List<Users> usersList = query.getResultList();
        List<String> returnList = new ArrayList<String>();
        for (Users u : usersList) {
            returnList.add("UserId:" + u.getId() + "; email:" + u.getEmail() + "; country:" + u.getCountry());
        }
        return returnList;
    }

    public void addNewOutletDataModel_Test(Long outletId) {
        OutletDataModel od = new OutletDataModel();
        od.setOutletId(outletId);
        em.persist(od);
    }

    public void removeNewOutletDataModel_Test() {
        Query query = em.createQuery("SELECT d FROM OutletDataModel d WHERE d.outletId >= 100000 AND d.outletId < 100021");
        List<OutletDataModel> dataModels = query.getResultList();
        for (OutletDataModel aModel : dataModels) {
            em.remove(aModel);
        }
    }

    public void updateOutletDataModel_Test(String customerEmail) {
        Query custQuery = em.createQuery("SELECT c FROM Users c WHERE c.email=: email");
        custQuery.setParameter("email", customerEmail);
        List<Users> users = custQuery.getResultList();
        Users selectedUser = users.get(0);

        Query query = em.createQuery("SELECT d FROM OutletDataModel d WHERE d.outletId > 100000 AND d.outletId < 100021");
        List<OutletDataModel> dataModels = query.getResultList();

        int ageIdx = this.computeAgeGroupsIdx(selectedUser);
        int countryIdx = this.computeCountriesIdx(selectedUser);

        for (int i = 0; i < 20; i++) {
            OutletDataModel aDataModel = dataModels.get(i);
            aDataModel.getCluster()[countryIdx][ageIdx] = new Long(i);
            em.persist(aDataModel);
        }
    }
}
